package com.zlq.cn.service.ai;

import com.alibaba.fastjson.JSON;
import com.aliyun.docmind_api20220711.Client;
import com.aliyun.docmind_api20220711.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zlq.cn.api.SignApiResult;
import com.zlq.cn.bootstrap.SignApiBootstrap;
import com.zlq.cn.config.FinderConfiguration;
import com.zlq.cn.entity.AsyncJob;
import com.zlq.cn.service.un.AsyncJobService;
import com.zlq.cn.service.un.ConfigService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class AliyunService implements ApplicationRunner {

    private final FinderConfiguration configuration;
    private final Client client;
    private boolean isRun = false;

    @Resource
    private AsyncJobService asyncJobService;
    @Resource
    private ConfigService configService;

    @SneakyThrows
    public AliyunService(FinderConfiguration configuration) {
        this.configuration = configuration;
        Config config = new Config()
                // 通过credentials获取配置中的AccessKey ID
                .setAccessKeyId(configuration.getAliyunAccessKeyId())
                // 通过credentials获取配置中的AccessKey Secret
                .setAccessKeySecret(configuration.getAliyunAccessSecret());
        // 访问的域名，支持ipv4和ipv6两种方式，ipv6请使用docmind-api-dualstack.cn-hangzhou.aliyuncs.com
        config.endpoint = "docmind-api.cn-hangzhou.aliyuncs.com";
        client = new Client(config);
    }

    @SneakyThrows
    public void submitConvertPdfToWordJob(SubmitConvertPdfToWordJobRequest request) {
        SubmitConvertPdfToWordJobResponse response = client.submitConvertPdfToWordJob(request);
        saveAsyncJob(response.getBody().getData().getId(), request, AsyncJob.ALI_AI_PDF_TO_WORD);
    }

    @SneakyThrows
    public void submitConvertImageToWordJob(SubmitConvertImageToWordJobRequest imageToWordJobRequest) {
        log.info(JSON.toJSONString(imageToWordJobRequest));
        SubmitConvertImageToWordJobResponse response = client.submitConvertImageToWordJob(imageToWordJobRequest);
        log.info(JSON.toJSONString(response));
        saveAsyncJob(response.getBody().getData().getId(), imageToWordJobRequest, AsyncJob.ALI_AI_IMAGE_TO_WORD);
    }

    @SneakyThrows
    public void submitConvertPdfToExcelJob(SubmitConvertPdfToExcelJobRequest request) {
        SubmitConvertPdfToExcelJobResponse response = client.submitConvertPdfToExcelJob(request);
        saveAsyncJob(response.getBody().getData().getId(), request, AsyncJob.ALI_AI_PDF_TO_EXCEL);
    }

    @SneakyThrows
    public void submitConvertImageToExcelJob(SubmitConvertImageToExcelJobRequest imageToExcelJobRequest) {
        SubmitConvertImageToExcelJobResponse response = client.submitConvertImageToExcelJob(imageToExcelJobRequest);
        saveAsyncJob(response.getBody().getData().getId(), imageToExcelJobRequest, AsyncJob.ALI_AI_IMAGE_TO_EXCEL);
    }

    @SneakyThrows
    public void submitConvertPdfToImageJobAdvance(SubmitConvertPdfToImageJobAdvanceRequest advanceRequest) {
        RuntimeOptions runtime = new RuntimeOptions();
        SubmitConvertPdfToImageJobResponse response = client.submitConvertPdfToImageJobAdvance(advanceRequest, runtime);
        saveAsyncJob(response.getBody().getData().getId(), advanceRequest, AsyncJob.ALI_AI_PDF_TO_IMAGE);
    }

    @SneakyThrows
    public void submitConvertImageToPdfJob(SubmitConvertImageToPdfJobRequest imageToPdfJobRequest) {
        SubmitConvertImageToPdfJobResponse response = client.submitConvertImageToPdfJob(imageToPdfJobRequest);
        saveAsyncJob(response.getBody().getData().getId(), imageToPdfJobRequest, AsyncJob.ALI_AI_IMAGE_TO_PDF);
    }

    public void saveAsyncJob(String id, Object param, String type) {
        AsyncJob asyncJob = new AsyncJob();
        asyncJob.setParam(id);
        asyncJob.setData(JSON.toJSONString(param));
        asyncJob.setType(type);
        asyncJob.setJobStatus(2);
        asyncJob.setCreateTime(LocalDateTime.now());
        asyncJob.setImei(SignApiBootstrap.requestFanYiUser().getFanyiUserImei());
        asyncJobService.save(asyncJob);
        isRun = true;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        isRun = true;
        runQueryTask();
    }

    @Scheduled(fixedDelay = 10000)
    public void runQueryTask() {
        if (isRun) {
            List<AsyncJob> list = asyncJobService.lambdaQuery()
                    .eq(AsyncJob::getJobStatus, 2)
                    .likeRight(AsyncJob::getType, "ali_ai_")
                    .list();
            if (CollectionUtils.isNotEmpty(list)) {
                for (AsyncJob asyncJob : list) {
                    try {
                        getDocumentConvertResult(asyncJob);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } else {
                isRun = false;
            }
        }
    }

    @SneakyThrows
    public void getDocumentConvertResult(AsyncJob asyncJob) {
        GetDocumentConvertResultRequest resultRequest = new GetDocumentConvertResultRequest();
        resultRequest.id = asyncJob.getParam();
        GetDocumentConvertResultResponse response = client.getDocumentConvertResult(resultRequest);
        GetDocumentConvertResultResponseBody body = response.getBody();
        Boolean completed = body.getCompleted();
        if (completed != null && completed) {
            SignApiResult result;
            if (Objects.equals("Success", body.getStatus())) {
                List<GetDocumentConvertResultResponseBody.GetDocumentConvertResultResponseBodyData> list = body.getData();
                for (GetDocumentConvertResultResponseBody.GetDocumentConvertResultResponseBodyData data : list) {
                    data.setUrl(configService.putObject("ali_ai/" + asyncJob.getType() + "/", data.getMd5() + "." + data.getType(), data.getUrl()));
                }
                asyncJob.setResultStatus(1);
                result = SignApiResult.resultSuccess(list);
            } else {
                asyncJob.setResultStatus(0);
                result = SignApiResult.resultError(body.getMessage());
            }
            asyncJob.setJobStatus(1);
            asyncJob.setResult(JSON.toJSONString(result));
            asyncJobService.updateById(asyncJob);
        }
    }
}
